<?php 
//  微博登录插件类，如有BUG请联系本人！！ 
/*===========================================================
*   name : 新浪微博
*   author : `Jn.Too'
*   QQ : 274987096
*   E-mail : 274987096@qq.com
*   VERSION : 1.2v
*   DATE : 2012-3-1
*   尊重作者,保留版权信息
*   版权所有 `Jn.Too'
*   使用；不允许对程序代码以任何形式任何目的的再发布。
**/

if (defined('WEBSITE'))
{
	global $_LANG;
	$_LANG['help']['APP_KEY'] = '在 open.weibo.com 里申请的 App Key';
	$_LANG['help']['APP_SECRET'] = '请注意填写，最长的就填此处';
	$_LANG['help']['weibo_version'] = '勾选使用 Oauth2.0版本 验证方法 , 否则采用 1.0a 版本验证方案';
	$_LANG['APP_KEY'] = 'App Key';
	$_LANG['APP_SECRET'] = 'App Secret';
	$_LANG['weibo_version'] = '是否使用Oauth2.0版本';
	
	
	$i = isset($web) ? count($web) : 0;
	
	// 类名
	$web[$i]['name'] = '新浪微博';
	
	// 文件名，不包含后缀
	
	$web[$i]['type'] = 'weibo';
	
	// 作者信息
	$web[$i]['author'] = '`Jn.Too\'';
	
	$web[$i]['className'] = 'weibo';
	
	// 作者QQ
	$web[$i]['qq'] = '274987096';
	
	// 作者邮箱
	$web[$i]['email'] = '274987096@qq.com';
	
	// 申请网址
	$web[$i]['website'] = 'http://open.weibo.com';
	
	// 版本号
	$web[$i]['version'] = '1.2v';
	
	// 更新日期
	$web[$i]['date']  = '2012-2-25';
	
	// 配置信息
	$web[$i]['config'] = array(
		
		array('type'=>'text' , 'name'=>'APP_KEY', 'value'=>''),
		array('type'=>'text' , 'name' => 'APP_SECRET' , 'value' => ''),
		array('type'=>'checkbox' , 'name' => 'weibo_version' , 'value' => '1'),
	);
}


if (!defined('WEBSITE'))
{
	if(!defined('weibo_version'))
	{
		class website extends cls_http
		{
			// 微博处取回的参数
			var $token = array( 'token' => '' , 'token_secret'=>'' );
			var $oauth = array();  // 获取了 token 之后的参数
			var $oauth_version = '1.0a';
			
			var $Consumer = array();
			var $signature_method = 'HMAC-SHA1';
			var $requestTokenURL = 'http://api.t.sina.com.cn/oauth/request_token';
			var $authorizeURL = 'http://api.t.sina.com.cn/oauth/authorize';
			var $authenticateURL = 'http://api.t.sina.com.cn/oauth/authenticate';
			var $accessTokenURL = 'http://api.t.sina.com.cn/oauth/access_token';
			var $userURL = 'http://api.t.sina.com.cn/users/show.json';
			
			
			// 构造函数
			var $error = array();
			
			function __construct()
			{
				$this->website();
			}
			function website()
			{
				$this->consumer['key'] = APP_KEY;
				$this->consumer['secret'] = APP_SECRET;
			}
			
			function login( $callblock )
			{
				if(!$this->request_token( $callblock )) 
				{
					return false;
				}
				return $this->getAuthorizeURL($this->token , false , $callblock);
			}
			
			function getAccessToken()
			{
				$this->token['token'] = $_REQUEST['ken'];
				$this->token['token_secret'] = $_REQUEST['ser'];
				
				$parameters = array();
				$parameters['oauth_verifier'] = $_REQUEST['oauth_verifier'];
				$request = urldecode($this->OAHttp($this->accessTokenURL , 'GET' , $parameters)); 
				if($request)
					parse_str($request , $token);
				if(!empty($token['oauth_token']))
				{
					$this->token = array('token' => $token['oauth_token'] , 'token_secret' => $token['oauth_token_secret'] , 'user_id' => $token['user_id']);
					return $this->token;
				}
				else
				{
					$this->error('user_token' , $token);
					return false;
				}
				return false;
			}
			function setAccessToken($token)
			{
				if(!$token)
				{
					$this->error('user_token' , '为空');
					return false;
				}
				$this->token = $token;
				return true;
			}
			function get_user_info()
			{
				$par = array();
				$par['user_id'] = $this->token['user_id'];
				$json = $this->OAHttp($this->userURL , 'GET' , $par);
				$result = json_decode($json , true);
				return $this->transferred($result);
			}
			
			function transferred($user_info)
			{
				$arr = array();
				if(!empty($user_info['error_code']))
				{
					$this->error('获取数据出错',$user_info);
					return false;
				}
				
				$arr['user_id'] = $user_info['id'];
				$arr['name'] = $user_info['name'];
				$arr['location'] = $user_info['location'];
				$arr['sex']  = $user_info['gender'] == 'm' ? '1' : '0';
				$arr['rank_id'] = RANK_ID;
				$arr['img'] = $user_info['profile_image_url'];
				$arr['user_info'] = $user_info;
				return $arr;
			}
			
			public function request_token( $callblock = '' )
			{
				$array = array();
				if($callblock)
				{
					$array['oauth_callback'] = urlencode($callblock);
				}
				$request = $this->OAHttp($this->requestTokenURL , 'GET' , $array);
				
				if($request)
					parse_str($request , $token);
				if(!empty($token['oauth_token']))
				{
					$this->token = array('token' => $token['oauth_token'] , 'token_secret' => $token['oauth_token_secret']);
					return true;
				}
				else
				{
					$this->error('request' , $token);
				}
				return false;
			}
			function getAuthorizeURL($token, $sign_in_with_Weibo = TRUE , $url) { 
				if (is_array($token)) $to = $token['token'];
				if (empty($sign_in_with_Weibo)) { 
					return $this->authorizeURL . "?oauth_token={$to}&oauth_callback=" . urlencode($url.'&ken='.$token['token'].'&ser='.$token['token_secret']); 
				} else { 
					return $this->authenticateURL . "?oauth_token={$to}&oauth_callback=". urlencode($url.'&ken='.$token['token'].'&ser='.$token['token_secret']); 
				}
			}
			
			public function OAHttp($url , $method , $parray = array())
			{
				$arr = $this->conStr();
				$this->oauth = array_merge($arr , $parray);
				$this->setsign($method , $url);
				return $this->http($url , $method , $this->oauth);
			}
			function conStr()
			{
				$oauth = array(
					'oauth_version' => $this->oauth_version,
					'oauth_nonce' => $this->generate_nonce(),
					'oauth_timestamp' => time(),
					'oauth_consumer_key' => $this->consumer['key'],
				);
				
				if(!empty($this->token['token']))
					$oauth['oauth_token'] = $this->token['token'];
				return $oauth;
			}
			
			function setsign($Method , $url)
			{
				$this->oauth['oauth_signature_method'] = $this->signature_method;
				$base_string = $this->base_String($Method , $url , $this->oauth);
				$sign = $this->signature($base_string , $this->consumer['secret'] , $this->token['token_secret']);
				$this->oauth['oauth_signature'] = $sign;
			}
			
			
			// 签名函数
			function signature ( $base_string, $consumer_secret, $token_secret )
			{
				$key_parts = array( $consumer_secret ,$token_secret);
				$key_parts = $this->urlencode_rfc3986($key_parts);
				
				$key = implode('&', $key_parts);
				if (function_exists('hash_hmac'))
				{
					$signature = base64_encode(hash_hmac("sha1", $base_string, $key, true));
				}
				else
				{
					$blocksize	= 64;
					$hashfunc	= 'sha1';
					if (strlen($key) > $blocksize)
					{
						$key = pack('H*', $hashfunc($key));
					}
					$key	= str_pad($key,$blocksize,chr(0x00));
					$ipad	= str_repeat(chr(0x36),$blocksize);
					$opad	= str_repeat(chr(0x5c),$blocksize);
					$hmac 	= pack(
								'H*',$hashfunc(
									($key^$opad).pack(
										'H*',$hashfunc(
											($key^$ipad).$base_string
										)
									)
								)
							);
					$signature = base64_encode($hmac);
				}
				return $signature;
			}
			
			// To Base_String
			
			function base_String($Method , $url ,$arr)
			{
				$parts = array( 
					$Method, 
					$url, 
					$this->build_http_query($arr),
				); 
				$st = $this->urlencode_rfc3986($parts);
				
				return implode('&', $st);
			}
			function generate_nonce() { 
				$mt = microtime(); 
				$rand = mt_rand(); 
				return md5($mt . $rand);
			}
			function urlencode_rfc3986($input) { 
				if (is_array($input)) { 
					$a = array_map(array($this , 'urlencode_rfc3986'), $input);
					return $a;
				} else if (is_scalar($input)) {
					return str_replace( 
						'+', 
						' ', 
						str_replace('%7E', '~', rawurlencode($input)) 
					); 
				} else { 
					return ''; 
				} 
			}
			function build_http_query($params) {
				if (!$params) return '';
				// Urlencode both keys and values
				$keys = $this->urlencode_rfc3986(array_keys($params));
				$values = $this->urlencode_rfc3986(array_values($params));
				$params = array_combine($keys, $values);
				// Parameters are sorted by name, using lexicographical byte value ordering. 
				// Ref: Spec: 9.1.1 (1) 
				uksort($params, 'strcmp');
				$pairs = array(); 
				foreach ($params as $parameter => $value) { 
					if (is_array($value)) { 
						natsort($value); 
						foreach ($value as $duplicate_value) { 
							$pairs[] = $parameter . '=' . $duplicate_value; 
						} 
					} else {
						$pairs[] = $parameter . '=' . $value;
					}
				}
				return implode('&', $pairs);
			}
			
			public function error($str , $msg) // 错误
			{
				if(is_array($msg))
					$this->add_error($msg['error_code'] , $msg['error'], $msg['request'].' - '.$msg['error_CN'] . ' - ' .$str );
				else
					$this->add_error($str , $msg);
			}
		}
	}
	else
	{
		include_once('cls_oauth2.php');
		
		class website extends oauth2
		{
			public $host = 'https://api.weibo.com/2/';
			
			
			function __construct()
			{
				$this->website();
			}
			function website()
			{
				$this->app_key = APP_KEY;
				$this->app_secret = APP_SECRET;
				$this->tokenURL = 'https://api.weibo.com/oauth2/access_token';
				$this->authorizeURL = 'https://api.weibo.com/oauth2/authorize';
				$this->display = 'popup';
			}
			
			function login($callblock)
			{
				return $this->getauthorizeURL($callblock);
			}
			function getAccessToken()
			{
				return $this->getToken('POST');
			}
			
			function setAccessToken($token)
			{
				$this->token = $token;
			}
			
			function get_user_info()
			{
				$slp = array();
				if(!empty($this->token['uid']))
				{
					$this->id_format($this->token['uid']);
					$slp['uid'] = $this->token['uid'];
				}
				$info = $this->oath2->getOauthMsg($this->host.'users/show.json' , 'GET' , $slp);
				return $this->setUser($info);
			}
			function setUser($info)
			{
				if(!empty($info['error']))
				{
					$this->error('get Token failed' , $info);
					return false;
				}
				$arr = array();
				$arr['user_id']  = $info['id'];
				$arr['name'] = empty($info['screen_name']) ? $info['name'] : $info['screen_name'];
				$arr['location'] = $info['location'];
				$arr['sex'] = $info['gender'] == 'm' ? 1 : 0;
				$arr['img']  = empty($info['avatar_large']) ? '' : $info['avatar_large'];
				$arr['lang'] = $info['lang'];
				$arr['info'] = $info;
				return $arr;
			}
			
			
			public function error($str , $msg) // 错误
			{
				if(is_array($msg))
					$this->add_error($msg['error_code'] , $msg['error'], $msg['request'].' - '.(isset($msg['error_description']) ? $msg['error_description'] : '') . ' - ' .$str );
				else
					$this->add_error($str , $msg);
			}
			function id_format(&$id) {
				if ( is_float($id) ) {
					$id = number_format($id, 0, '', '');
				} elseif ( is_string($id) ) {
					$id = trim($id);
				}
			}
		}
	}
}
?>